package com.xxxx.sso.service.impl;


import com.xxxx.common.pojo.Admin;
import com.xxxx.common.pojo.AdminExample;
import com.xxxx.common.utils.JsonUtil;
import com.xxxx.common.utils.MD5Util;
import com.xxxx.sso.mapper.AdminMapper;
import com.xxxx.sso.service.SSOService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 单点登录实现类
 *
 * @Author GP
 * @Date 2020/8/31 16:02
 */
@Service(interfaceClass = com.xxxx.sso.service.SSOService.class)
@Component
public class SSOServiceImpl implements SSOService {


    @Resource
    private AdminMapper adminMapper;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Value("${user.ticket}")
    private String userTicket;

    /**
     * 登录验证，返回ticket
     * 1、判断前台传回的username，password是否为空
     * 为空: 打印信息 return
     * 2、从数据库中查询是否存在此用户
     * 多个或不存在：打印信息，return
     * 3、生成ticket；
     * 将ticket(key)、用户信息(value)存入Redis中
     * 返回ticket
     */
    @Override
    public String login(Admin admin) {
        //1、判断username，password是否为空
        if (StringUtils.isEmpty(admin.getUserName())) {
            System.out.println("用户名不能为空");
            return null;
        }
        if (StringUtils.isEmpty(admin.getPassword())) {
            System.out.println("用户密码不能为空！");
            return null;
        }

        //2、从数据库中查询是否存在此用户
        //根据用户名查询用户信息
        AdminExample adminExample = new AdminExample();
        adminExample.createCriteria().andUserNameEqualTo(admin.getUserName());
        List<Admin> admins = adminMapper.selectByExample(adminExample);
        //判断用户是否为空
        if (CollectionUtils.isEmpty(admins) || admins.size()>1) {
            System.out.println("用户不存在");
            return null;
        }
        //校验数据库中密码和前台传回的密码是否相同
        //先将密码加密再与数据库中密码比较
        String password = MD5Util.md5Encrypt32Upper(admin.getPassword());
        if (!password.equals(admins.get(0).getPassword())) {
            System.out.println("密码不正确！");
            return null;
        }

        //3、返回ticket，将ticket、用户信息存入redis,
        //登录成功，生成ticket(UUID生成唯一)
        String ticket = UUID.randomUUID().toString().replace("-","");
            System.out.println("生成票据："+ ticket);
        //将ticket存入redis
        ValueOperations<String, String> value = redisTemplate.opsForValue();
            System.out.println(JsonUtil.object2JsonStr(admins.get(0)));
        //key:存储ticket票据信息，value：存储用户信息
        //JsonUtil.object2JsonStr(..)将对象转换成json字符串,设置失效时间
        value.set(userTicket+":"+ticket, JsonUtil.object2JsonStr(admins.get(0)),30, TimeUnit.MINUTES);
        //浏览器cookie设置ticket（在shop-manager中设置）

        return ticket;
    }

    /**
     * 验证ticket
     * 1、判断ticket是否为空
     *      为空，return
     * 2、判断Redis中ticket是否存在
     *      不存在 return
     * 3、返回用户信息
     */
    @Override
    public Admin VerifyTicket(String ticket) {
        //1、判断ticket是否为空
        if (StringUtils.isEmpty(ticket)) {
            System.out.println("ticket为空！");
            return null;
        }
        //2、判断Redis中ticket是否存在
        ValueOperations<String, String> value = redisTemplate.opsForValue();
        //根据ticket从Redis中获取用户信息，得到的是Json格式的字符串
        String admin = value.get(userTicket + ":" + ticket);
        if (StringUtils.isEmpty(admin)) {
            System.out.println("Redis中不存在ticket");
            return null;
        }
        //3、验证成功，返回用户信息
        //将字符串转换成对象
        return JsonUtil.jsonStr2Object(admin, Admin.class);
    }

    /**
     * 安全退出
     * 删Redis
     *
     * @param ticket
     */
    @Override
    public void logout(String ticket) {
        redisTemplate.delete(userTicket + ":" + ticket);
    }
}
